package cn.cttic.app.service.impl;

import cn.cttic.app.utils.OrderHelper;
import cn.cttic.base.api.domain.BaseCompany;
import cn.cttic.base.api.domain.BaseDevice;
import cn.cttic.base.api.domain.BaseProduct;
import cn.cttic.base.api.domain.BaseUser;
import cn.cttic.common.core.domain.R;
import cn.cttic.common.core.service.DictService;
import cn.cttic.link.api.RemoteThirdSmsService;
import cn.cttic.order.api.domain.BaseInstallOrder;
import cn.cttic.order.api.domain.BaseSaleOrder;
import cn.cttic.resource.api.domain.RemoteSms;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.cttic.app.api.domain.vo.MobileSaleOrderInfoVo;
import cn.cttic.app.api.domain.vo.MobileSalesmanInfoVo;
import cn.cttic.app.api.enums.Gender;
import cn.cttic.app.api.enums.SaleOrderStatus;
import cn.cttic.app.mapper.*;
import cn.cttic.app.service.IAppInstallService;
import cn.cttic.app.service.IAppSaleService;
import cn.cttic.common.core.exception.app.AppException;
import cn.cttic.common.satoken.model.AppLoginUser;
import cn.cttic.common.satoken.utils.AppLoginHelper;
import cn.cttic.resource.api.RemoteFileService;
import cn.cttic.resource.api.RemoteSmsService;
//import cn.cttic.resource.api.domain.GySmsResponse;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @Implementation: 微信小程序销售接口
 * @Author: Times.Studio
 * @Date: 2024.05.15
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AppSaleServiceImpl implements IAppSaleService {

    private final BaseSaleOrderMapper baseSaleOrderMapper;

    private final BaseInstallOrderMapper baseInstallOrderMapper;

    private final BaseCompanyMapper baseCompanyMapper;

    private final BaseUserMapper baseUserMapper;

    private final BaseProductMapper baseProductMapper;

    private final BaseDeviceMapper baseDeviceMapper;

    private final IAppInstallService appInstallService;

    @DubboReference
    private RemoteFileService remoteFileService;

    @DubboReference
    private RemoteThirdSmsService remoteSmsService;

    private final DictService dictService;

    private final OrderHelper orderHelper;

    /**
     * 创建销售订单
     *
     * @param productId 产品ID
     * @param lastName  姓氏
     * @param gender    性别
     * @param phone     手机号
     * @param smsCode   短信验证码
     * @param carNo     卡号
     * @return
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public BaseSaleOrder createSaleOrder(
        String productId,
        String lastName,
        Integer gender,
        String phone,
        String smsCode,
        String carNo
    ) {

        // 获取APP登录用户
        AppLoginUser appLoginUser = AppLoginHelper.getAppLoginUser();
        if (ObjectUtil.isEmpty(appLoginUser)) {
            throw new AppException("10010", "未找到登录用户");
        } else if (appLoginUser.getType().equals("0")) {
            throw new AppException("10011", "用户类型不匹配");
        }

        // 创建订单
        BaseSaleOrder baseSaleOrder = new BaseSaleOrder();
        baseSaleOrder.setId(orderHelper.getSaleOrderId());
        baseSaleOrder.setProductId(productId);
        baseSaleOrder.setLastName(lastName);
        baseSaleOrder.setStatus(SaleOrderStatus.WAITING.getValue());
        baseSaleOrder.setGender(gender);
        baseSaleOrder.setCreateBy(Long.parseLong(appLoginUser.getUserId()));
        baseSaleOrder.setCreateTime(new Date());
        baseSaleOrder.setPhone(phone);
        baseSaleOrder.setCarNo(carNo);
        baseSaleOrder.setSalesManId(appLoginUser.getUserId());

        int ret = baseSaleOrderMapper.insert(baseSaleOrder);
        if (ret <= 0) {
            throw new AppException("10012", "创建销售订单失败");
        }

        String callerName = lastName + Gender.of(gender).getLabel();

        // 创建安装单，触发异常则返回
        BaseInstallOrder baseInstallOrder = appInstallService.createInstallOrder(baseSaleOrder);
        baseSaleOrder.setInstallOrderId(baseInstallOrder.getId());
        ret = baseSaleOrderMapper.updateById(baseSaleOrder);
        if (ret <= 0) {
            throw new AppException("10012", "创建销售订单失败");
        }

        RemoteSms smsResponse = remoteSmsService.sendInstallCustomerNotice(
            phone,
            callerName,
            baseInstallOrder.getInstallCode(),
            baseInstallOrder.getInstallUrl()
        );
        if (!smsResponse.getSuccess()) {
            log.error("短信发送异常 => {}", smsResponse);
            throw new AppException("10012", "创建销售订单失败");
        } else {
            baseInstallOrder.setNoticeSmsId(smsResponse.getConfigId());
            baseInstallOrder.setNoticeStatus(1);
            ret = baseInstallOrderMapper.updateById(baseInstallOrder);
            if (ret <= 0) {
                log.error("短信发送成功但是存储异常=> {}", smsResponse);
                throw new AppException("10012", "创建销售订单失败");
            }
            log.info("短信发送情况： {}", smsResponse);
        }

        return baseSaleOrder;
    }

    /**
     * 获取销售订单信息
     *
     * @param orderNo 销售订单号
     * @return
     */
    @Override
    public MobileSaleOrderInfoVo getSaleOrderInfo(String orderNo) {

        AppLoginUser appLoginUser = AppLoginHelper.getAppLoginUser();

        BaseUser baseUser = baseUserMapper.selectById(appLoginUser.getUserId());

        BaseSaleOrder saleOrder = baseSaleOrderMapper.selectOne(
            new LambdaQueryWrapper<BaseSaleOrder>()
                .eq(BaseSaleOrder::getId, orderNo)
        );

        if (saleOrder == null) {
            throw new AppException("10021", "未查询到销售订单");
        }

        MobileSaleOrderInfoVo mobileSaleOrderInfoVo = new MobileSaleOrderInfoVo();
        mobileSaleOrderInfoVo.setOrderId(saleOrder.getId());
        mobileSaleOrderInfoVo.setOrderStatus(saleOrder.getStatus());
        mobileSaleOrderInfoVo.setOrderStatusName(SaleOrderStatus.of(saleOrder.getStatus()).getLabel());

        String customerName = saleOrder.getLastName();
        String callerName = Gender.of(saleOrder.getGender()).getLabel();
        mobileSaleOrderInfoVo.setCustomerName(customerName + callerName);

        mobileSaleOrderInfoVo.setCustomerPhone(saleOrder.getPhone());
        mobileSaleOrderInfoVo.setCustomerCarNo(saleOrder.getCarNo());

        BaseProduct baseProduct = baseProductMapper.selectById(saleOrder.getProductId());
        String productPosterUrl = remoteFileService.selectUrlByIds(baseProduct.getProductPoster());
        String productThumbnailUrl = remoteFileService.selectUrlByIds(baseProduct.getProductThumbnail());

        mobileSaleOrderInfoVo.setProductThumbnail(ObjectUtil.isEmpty(productThumbnailUrl) ? productPosterUrl : productThumbnailUrl);
        mobileSaleOrderInfoVo.setProductName(baseProduct.getProductName());
        mobileSaleOrderInfoVo.setProductId(baseProduct.getId());

        BaseDevice baseDevice = baseDeviceMapper.selectById(baseProduct.getDeviceId());
        String devicePosterUrl = remoteFileService.selectUrlByIds(baseDevice.getDevicePoster());
        String deviceThumbnailUrl = remoteFileService.selectUrlByIds(baseDevice.getDeviceThumbnail());
        mobileSaleOrderInfoVo.setDeviceId(baseDevice.getId());
        mobileSaleOrderInfoVo.setDeviceName(baseDevice.getDeviceName());

        BaseCompany baseCompany = baseCompanyMapper.selectById(baseUser.getCompanyId());
//        BaseSaleChannel baseSaleChannel = baseSaleChannelMapper.selectOne(
//            new LambdaQueryWrapper<BaseSaleChannel>()
//                .eq(BaseSaleChannel::getChannelCode, baseCompany.getChannelCode())
//        );

        MobileSalesmanInfoVo salesmanInfo = new MobileSalesmanInfoVo();
        salesmanInfo.setSaleOrderNo(saleOrder.getId());
        salesmanInfo.setSalesmanCompany(baseCompany.getCompanyName());
        salesmanInfo.setSalesChannel(dictService.getDictLabel("dict_channel_type", baseCompany.getChannelType()));
        salesmanInfo.setSalesmanName(baseUser.getRealName());
        salesmanInfo.setSalesmanPhone(baseUser.getPhone());
        salesmanInfo.setSaleOrderTime(LocalDateTimeUtil.of(saleOrder.getCreateTime()));

        mobileSaleOrderInfoVo.setSalesmanInfo(salesmanInfo);

        BaseInstallOrder installOrder = baseInstallOrderMapper.selectOne(
            new LambdaQueryWrapper<BaseInstallOrder>()
                .eq(BaseInstallOrder::getSaleOrderId, saleOrder.getId())
        );

        if (installOrder != null) {
            mobileSaleOrderInfoVo.setCustomerInstallCode(installOrder.getInstallCode());
        }

        return mobileSaleOrderInfoVo;
    }
}
